package com.aizuda.boot.modules.business.employee.provider.impl;

import com.aizuda.boot.modules.business.contract.dto.UserInfo;
import com.aizuda.boot.modules.business.contract.util.AuthUtil;
import com.aizuda.boot.modules.business.employee.service.EmployeeService;
import com.aizuda.boot.modules.business.department.domain.response.EmployeePermissionVO;
import com.aizuda.boot.modules.business.employee.domain.request.EmployeeQueryById;
import com.aizuda.boot.modules.business.employee.domain.request.EmployeeQueryVO;
import com.aizuda.boot.modules.business.employee.domain.response.EmployeeQueryShowVO;
import com.aizuda.boot.modules.business.employee.provider.EmployeeProvider;
import com.aizuda.boot.modules.business.permission.domain.entity.*;
import com.aizuda.boot.modules.business.permission.service.RoleDataIsolationService;
import com.aizuda.boot.modules.business.permission.service.RoleEmployeeScopeRelService;
import com.aizuda.boot.modules.business.permission.service.RolePermissionService;
import com.aizuda.boot.modules.business.permission.service.RoleService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.*;
import java.util.stream.Collectors;

@Service
@Slf4j
public class EmployeeProviderImpl implements EmployeeProvider {

    @Autowired
    private EmployeeService employeeService;
    @Autowired
    private RoleService roleService;
    @Autowired
    private RolePermissionService rolePermissionService;
    @Resource
    private RoleDataIsolationService roleDataIsolationService;
    @Autowired
    private RoleEmployeeScopeRelService roleEmployeeScopeRelService;

    @Override
    public List<EmployeeQueryShowVO> queryEmployee(EmployeeQueryVO query) {
        // 获取当前用户信息
        UserInfo currentUser = AuthUtil.getCurrentUser();
        if (Objects.isNull(currentUser)) {
            log.warn("当前用户未登录，无法查询员工信息");
            return new ArrayList<>();
        }



        try {
            // 调用service层方法查询员工
            List<EmployeeQueryShowVO> employeeList = employeeService.queryEmployee(query);

            if (CollectionUtils.isEmpty(employeeList)) {
//                log.info("未找到符合条件的员工信息，查询条件：{}", JSON.toJSONString(query));
                return new ArrayList<>();
            }

            log.info("成功查询到{}名员工", employeeList.size());
            return employeeList;
        } catch (Exception e) {
//            log.error("查询员工信息时发生异常，查询条件：{}", JSON.toJSONString(query), e);
            return new ArrayList<>();
        }
    }

    @Override
    public List<EmployeeQueryShowVO> queryEmployee(EmployeeQueryById employeeIds) {
        // 参数验证
        if (CollectionUtils.isEmpty(employeeIds.getEmployeeIds())) {
            log.warn("员工ID列表为空，返回空结果");
            return new ArrayList<>();
        }

        // 获取当前用户信息（用于日志记录）
        UserInfo currentUser = AuthUtil.getCurrentUser();
        if (Objects.isNull(currentUser)) {
            log.warn("当前用户未登录，不允许查询员工信息");
        }

        try {
            // 调用service层方法查询员工
            List<EmployeeQueryShowVO> employeeList = employeeService.queryEmployeeByIds(employeeIds.getEmployeeIds());

            if (CollectionUtils.isEmpty(employeeList)) {
                log.info("根据员工ID列表未找到符合条件的员工信息，员工ID列表：{}", employeeIds);
                return new ArrayList<>();
            }

            log.info("根据员工ID列表成功查询到{}名员工，输入ID数量：{}", employeeList.size(), employeeIds.getEmployeeIds().size());
            return employeeList;
        } catch (Exception e) {
            log.error("根据员工ID列表查询员工信息时发生异常，员工ID列表：{}", employeeIds, e);
            return new ArrayList<>();
        }
    }

    @Override
    public EmployeePermissionVO queryPermission() {
        UserInfo currentUser = AuthUtil.getCurrentUser();
        if (Objects.isNull(currentUser)) {
            log.warn("当前用户未登录，无法查询员工权限信息");
            return new EmployeePermissionVO();
        }

        EmployeeEntity employee = employeeService.getOne(new LambdaQueryWrapper<EmployeeEntity>()
                .eq(EmployeeEntity::getId, currentUser.getEmployeeId())
                .eq(EmployeeEntity::getWorkStatus, 1L));
        if (Objects.isNull(employee)) {
            log.warn("未找到员工信息，employeeId: {}", currentUser.getEmployeeId());
            return new EmployeePermissionVO();
        }

        // 获取当前员工的基本权限信息（主租户信息）
        EmployeePermissionVO result = employeeService.queryPermission(currentUser.getEmployeeId());
        if (Objects.isNull(result)) {
            log.warn("为查询到员工入职部门信息，employeeId: {}", currentUser.getEmployeeId());
        }
        // 获取当前用户其他租户下的用户及权限
        List<EmployeeEntity> list = employeeService.list(new LambdaQueryWrapper<EmployeeEntity>()
                .eq(EmployeeEntity::getMobile, employee.getMobile())
                .eq(EmployeeEntity::getWorkStatus, 1L));


        // 封装多租户权限信息
        List<EmployeePermissionVO.OwnPermissionVO> ownPermissions = new ArrayList<>();

        if (!CollectionUtils.isEmpty(list)) {
            // 遍历所有租户下的用户记录
            for (EmployeeEntity tenantEmployee : list) {
                try {
                    // 获取员工在该租户下的部门信息
                    EmployeePermissionVO employeePermission = employeeService.queryPermission(tenantEmployee.getId());
                    if (Objects.isNull(employeePermission)) {
                        log.debug("员工 {} 在租户下无部门信息，跳过", tenantEmployee.getId());
                        continue;
                    }

                    // 创建权限对象
                    EmployeePermissionVO.OwnPermissionVO ownPermission = new EmployeePermissionVO.OwnPermissionVO();

                    // 设置员工基本信息
                    ownPermission.setEmployeeId(tenantEmployee.getId());
                    ownPermission.setName(tenantEmployee.getName());
                    ownPermission.setAliasName(tenantEmployee.getAliasName());
                    ownPermission.setAvatar(tenantEmployee.getAvatar());

                    // 设置部门信息
                    ownPermission.setDeptId(employeePermission.getDeptId());
                    ownPermission.setDeptName(employeePermission.getDeptName());

                    // 设置租户信息
                    ownPermission.setTenantKey(employeePermission.getTenantKey());
                    ownPermission.setTenantName(employeePermission.getTenantName());

                    // 查询员工角色信息
                    List<RoleEmployeeScopeRelEntity> roleInfos = roleEmployeeScopeRelService.list(new LambdaQueryWrapper<RoleEmployeeScopeRelEntity>()
                            .eq(RoleEmployeeScopeRelEntity::getEmployeeId, tenantEmployee.getId()));
                    List<EmployeePermissionVO.RoleVo> roles = new ArrayList<>();
                    Set<String> allDataPermissionCodes = new HashSet<>(); // 收集所有数据权限代码

                    if (!CollectionUtils.isEmpty(roleInfos)) {
                        List<Long> roleIds = roleInfos.stream()
                                .filter(info -> Objects.nonNull(info) && Objects.nonNull(info.getId()))
                                .map(RoleEmployeeScopeRelEntity::getRoleId)
                                .collect(Collectors.toList());

                        if (!CollectionUtils.isEmpty(roleIds)) {
                            // 获取角色详细信息
                            List<RoleEntity> roleEntities = roleService.listByIds(roleIds);

                            // 处理每个角色的权限
                            for (RoleEntity roleEntity : roleEntities) {
                                if (Objects.isNull(roleEntity)) {
                                    continue;
                                }

                                EmployeePermissionVO.RoleVo roleVo = new EmployeePermissionVO.RoleVo();
                                roleVo.setRoleId(Math.toIntExact(roleEntity.getId()));
                                roleVo.setRoleName(roleEntity.getRoleName());

                                // 1. 查询并封装rolePermissions属性（从auth_role_permission表查询）
                                Map<String, String> rolePermissionMap = getRolePermissions(roleEntity.getId());
                                roleVo.setRolePermissions(rolePermissionMap);

                                roles.add(roleVo);
                            }

                            // 2. 查询并封装permissions属性（从auth_role_data_isolation表查询）
                            allDataPermissionCodes = getDataPermissions(roleIds, tenantEmployee.getId(),
                                    employeePermission.getDeptId());
                        }
                    }

                    // 生成权限列表（基于auth_role_data_isolation表的数据权限）
                    List<EmployeePermissionVO.PermissionVO> permissions = new ArrayList<>();
                    if (!allDataPermissionCodes.isEmpty()) {
                        int permissionId = 1;
                        for (String permissionCode : allDataPermissionCodes) {
                            EmployeePermissionVO.PermissionVO permissionVO = new EmployeePermissionVO.PermissionVO();
                            permissionVO.setPermissionId(permissionId++);
                            permissionVO.setPermissionName(permissionCode);
                            permissions.add(permissionVO);
                        }
                    }

                    // 设置角色和权限信息
                    ownPermission.setRoles(roles);
                    ownPermission.setPermissions(permissions);

                    // 添加到结果列表
                    ownPermissions.add(ownPermission);

                    log.debug("成功封装员工 {} 在租户 {} 下的权限信息，角色数：{}，数据权限数：{}",
                            tenantEmployee.getId(), employeePermission.getTenantKey(), roles.size(), permissions.size());

                } catch (Exception e) {
                    log.error("获取员工权限信息失败，employeeId: {}", tenantEmployee.getId(), e);
                    // 继续处理下一个员工，不中断整个流程
                }
            }
        }

        // 设置最终的权限信息
        if (Objects.nonNull(result)) {
            result.setOwnPermission(ownPermissions);
        } else {
            // 如果主租户信息为空，创建基本结构
            result = new EmployeePermissionVO();
            result.setEmployeeId(employee.getId());
            result.setName(employee.getName());
            result.setAliasName(employee.getAliasName());
            result.setAvatar(employee.getAvatar());
            result.setOwnPermission(ownPermissions);
        }

        log.info("成功查询到用户 {} 在 {} 个租户下的权限信息，总权限记录：{}",
                employee.getMobile(), ownPermissions.size(),
                ownPermissions.stream().mapToInt(op -> op.getPermissions().size()).sum());

        return result;
    }

    /**
     * 查询角色功能权限信息（从auth_role_permission表查询）
     *
     * @param roleId 角色ID
     * @return 权限映射表
     */
    private Map<String, String> getRolePermissions(Long roleId) {
        List<RolePermissionEntity> rolePermissions = rolePermissionService.list(
                new LambdaQueryWrapper<RolePermissionEntity>()
                        .eq(RolePermissionEntity::getRoleId, roleId));

        Map<String, String> rolePermissionMap = new HashMap<>();
        if (!CollectionUtils.isEmpty(rolePermissions)) {
            rolePermissionMap = rolePermissions.stream()
                    .filter(rp -> Objects.nonNull(rp) && StringUtils.isNotBlank(rp.getPermissionCode()))
                    .collect(Collectors.toMap(
                            RolePermissionEntity::getPermissionCode,
                            rp -> StringUtils.isNotBlank(rp.getPermissionValue()) ? rp.getPermissionValue() : "",
                            (existing, replacement) -> existing // 保留已存在的值
                    ));
        }

        log.debug("查询角色 {} 功能权限，共 {} 个权限", roleId, rolePermissionMap.size());
        return rolePermissionMap;
    }

    /**
     * 查询数据权限信息（从auth_role_data_isolation表查询）
     * 包含：当前角色权限、所在部门权限、直接绑定权限
     * 注意：角色、部门、用户三个字段是互斥的（三选一）
     *
     * @param roleIds    角色ID列表
     * @param employeeId 员工ID
     * @param deptId     部门ID
     * @return 数据权限代码集合
     */
    private Set<String> getDataPermissions(List<Long> roleIds, Long employeeId, Long deptId) {
        Set<String> allDataPermissionCodes = new HashSet<>();

        // 获取当前用户相关的字符串标识
        String currentEmployeeId = String.valueOf(employeeId);
        String currentDeptId = deptId != null ? String.valueOf(deptId) : "";

        // 查询所有数据权限记录，避免使用LIKE造成的误匹配
        List<RoleDataIsolationEntity> allDataIsolations = roleDataIsolationService.list();

        if (!CollectionUtils.isEmpty(allDataIsolations)) {
            // 在内存中进行精确过滤权限记录
            List<RoleDataIsolationEntity> validDataPermissions = allDataIsolations.stream()
                    .filter(rp -> {
                        if (Objects.isNull(rp) || StringUtils.isBlank(rp.getPermissionName())) {
                            return false;
                        }

                        // 1. 角色权限：有roleId且在当前用户角色列表中，userId和departmentId为空
                        if (Objects.nonNull(rp.getRoleId())) {

                            if (!CollectionUtils.isEmpty(roleIds) && roleIds.contains(rp.getRoleId())) {
                                log.debug("用户 {} 匹配到角色权限：{} (角色ID: {})", employeeId, rp.getPermissionName(), rp.getRoleId());
                                return true;
                            }
                        }

                        // 2. 用户权限：userId字段精确包含当前用户ID（避免LIKE的误匹配）
                        if (StringUtils.isNotBlank(rp.getUserId())) {
                            String[] userIds = rp.getUserId().split(",");
                            boolean userMatch = Arrays.stream(userIds)
                                    .map(String::trim)
                                    .anyMatch(uid -> uid.equals(currentEmployeeId));
                            if (userMatch) {
                                log.debug("用户 {} 匹配到直接用户权限：{} (用户ID列表: {})", employeeId, rp.getPermissionName(), rp.getUserId());
                                return true;
                            }
                        }

                        // 3. 部门权限：departmentId字段精确包含当前部门ID（避免LIKE的误匹配）
                        if (StringUtils.isNotBlank(rp.getDepartmentId()) && StringUtils.isNotBlank(currentDeptId)) {
                            String[] deptIds = rp.getDepartmentId().split(",");
                            boolean deptMatch = Arrays.stream(deptIds)
                                    .map(String::trim)
                                    .anyMatch(did -> did.equals(currentDeptId));
                            if (deptMatch) {
                                log.debug("用户 {} 通过部门 {} 匹配到部门权限：{} (部门ID列表: {})", employeeId, deptId, rp.getPermissionName(), rp.getDepartmentId());
                                return true;
                            }
                        }

                        return false;
                    })
                    .collect(Collectors.toList());

            // 收集所有有效的数据权限代码
            validDataPermissions.stream()
                    .forEach(rp -> allDataPermissionCodes.add(rp.getPermissionName()));

            log.debug("用户 {} 数据权限匹配情况：总权限记录 {}，有效权限 {}，当前员工ID：{}，当前部门ID：{}",
                    employeeId, allDataIsolations.size(), validDataPermissions.size(),
                    currentEmployeeId, currentDeptId);
        }

        return allDataPermissionCodes;
    }

}
